/**
 * Copyright (c) 2007,中企动力华南研发中心
 * All rights reserved.
 */

package com.ce.pms.authorization.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.ce.component.authorization.external.service.IAuthFunctionEntityManagementService;
import com.ce.component.authorization.external.service.IBizSystemAuthorizationService;
import com.ce.component.common.exception.ObjectNotFoundException;
import com.ce.component.uams.client.service.IBizSystemAccountService;
import com.ce.component.uams.model.ComAcctBizSystemAccountDO;
import com.ce.pms.authorization.model.AuthorizedInfo;
import com.ce.pms.common.service.IOrganizationalStructureService;
import com.ce.pms.common.vo.OrganizationalStructureVO;
import com.ce.pms.login.web.LoginAction;
import com.ce.util.BlankUtil;

/**
 * 权限控制过滤器，保证用户信息的线程安全
 *
 * @author  编写日期：2007年11月15日
 */
public class PmsAuthenticateFilter implements Filter {

	public  static  final String  USER_RIGHT_TYPE_MENU = "MENUS";
	public  static  final String  USER_RIGHT_TYPE_URL = "URL";
	public  static  final String  USER_RIGHT_TYPE_BUTTON = "BUTTONS";

	public  static  final String  LOGIN_USER_KEY = "loginUser";
	public  static  final String  LOGIN_USER_RIGHT_KEY = "loginUserRight";
	private  static  final String  BIZ_SYSTEM_SERIAL_NUMBER_KEY = "bizSystemSerialNumber";
	private  static final String BIZ_SYSTEM_ACCOUNT_SERVICE_KEY = "comUamsBizSystemAccountService";
	private  static final String BIZ_SYSTEM_RIGHT_SERVICE_KEY ="comAuthAuthorizationService";

	public  static final String BIZ_SYSTEM__ALLRIGHT_SERVICE_KEY ="comAuthFunctionEntityManagementService";
	private String bizSystemSerialNumber = null;
	private WebApplicationContext applicationContext = null;

	/**
	 * 处理页面URL权限控制，把用户信息保存在当前用户线程
	 *
	 * @param request
	 * @param response
	 * @param filterChain
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
		HttpServletRequest servletRequest = (HttpServletRequest) request;

		//单点登陆删除 begin
		String url = servletRequest.getRequestURI();
		String temp = url.substring(url.lastIndexOf("/") + 1, url.length());
		String ignoreUrl = applicationContext.getMessage(temp, null,"", servletRequest.getLocale());
		if (!"".endsWith(ignoreUrl)) {
			filterChain.doFilter(request, response);
			return;
		}
		String islogin=(String)servletRequest.getSession().getAttribute(LoginAction.LOGIN_USER);
		if(islogin==null){
			forwardPage(request, response, "loginres.jsp");//删除单点登陆时删除
			return;
		}
//		单点登陆删除 end

		if(!isUserInfoInSession(servletRequest))
		{
			OrganizationalStructureVO organizationalStructureVO = loadUserInfoVO(servletRequest);
			//如果organizationalStructureVO为空，说明只用登陆用户，当是还没有相应的组织架构信息，也就是没有该员工信息
			if(BlankUtil.isBlank(organizationalStructureVO)){
				servletRequest.getSession().invalidate();//清空session

			//	forwardPage(request, response, "logout.jsp");//删除单点登陆时打开

				forwardPage(request, response, "loginres.jsp");//删除单点登陆时删除
				return ;
			}
			addUserInfoToSession(servletRequest.getSession(), organizationalStructureVO);
			AuthorizedInfo authorizedInfo=loadUserRights(servletRequest.getSession(),servletRequest);
			addUserRightToSession(servletRequest.getSession(),authorizedInfo);

		}
 		filterChain.doFilter(request, response);
	}

	/**
	 * 将用户登录权限信息保存到session中
	 * @param session
	 * @param authorizedInfo
	 */
	private void addUserRightToSession(HttpSession session, AuthorizedInfo authorizedInfo)
	{
		session.setAttribute(LOGIN_USER_RIGHT_KEY, authorizedInfo);
	}

	/**
	 * 将用户登录信息保存到session中
	 * @param session
	 * @param userinfoVO
	 */
	private void addUserInfoToSession(HttpSession session, OrganizationalStructureVO organizationalStructureVO)
	{
		session.setAttribute(LOGIN_USER_KEY, organizationalStructureVO);
	}

	/**
	 * 获取登陆用户信息
	 * @param request
	 * @return
	 */
	private OrganizationalStructureVO loadUserInfoVO(HttpServletRequest request){
		IBizSystemAccountService accountService = (IBizSystemAccountService)applicationContext.getBean(BIZ_SYSTEM_ACCOUNT_SERVICE_KEY);
		IOrganizationalStructureService organizationalStructureService = (IOrganizationalStructureService)applicationContext.getBean("organizationalStructureService");
		String username = getCurrentLoginName(request);
		ComAcctBizSystemAccountDO accountDo = null;
		try
		{
			OrganizationalStructureVO organizationalStructureVO = new OrganizationalStructureVO();

//			organizationalStructureVO.setUserCode(username);
//			organizationalStructureVO.setAccountId(new Long(215));
			accountDo = accountService.getBizSystemAccountByLoginName(username, this.bizSystemSerialNumber);
			organizationalStructureVO=organizationalStructureService.queryUserByUserCode(username);
            if(!BlankUtil.isBlank(organizationalStructureVO)){
            	organizationalStructureVO.setAccountId(accountDo.getAccountId());
            }

			return organizationalStructureVO;
		}
		catch(Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	private AuthorizedInfo loadUserRights(HttpSession session,HttpServletRequest request){
		IBizSystemAuthorizationService rightService=(IBizSystemAuthorizationService)applicationContext.getBean(BIZ_SYSTEM_RIGHT_SERVICE_KEY);
		IAuthFunctionEntityManagementService authFunctionEntityManagementService=(IAuthFunctionEntityManagementService)applicationContext.getBean(BIZ_SYSTEM__ALLRIGHT_SERVICE_KEY);

		AuthorizedInfo authInfo = new AuthorizedInfo();

		OrganizationalStructureVO organizationalStructureVO =(OrganizationalStructureVO)session.getAttribute(LOGIN_USER_KEY);
		/*从权限组件获得当前登录用户URL权限，为字符串数组，如其中某个字符串为：IndexAction.do?method=list*/
		List<String> urlList = rightService.getAllFunctionEntitiesByType(organizationalStructureVO.getAccountId(), USER_RIGHT_TYPE_URL,null);
		Map<String ,String> mapUrl=new HashMap();
		if(!BlankUtil.isBlank(urlList)){
        	 for(String tempUrlList:urlList){
        		 mapUrl.put(tempUrlList.trim(), tempUrlList.trim());
             }
        	 urlList=null;
         }

		//从权限组件获得当前登录用户MENU权限，即菜单权限，为字符串数组
		List<String> menuIDList = rightService.getAllFunctionEntitiesByType(organizationalStructureVO.getAccountId(), USER_RIGHT_TYPE_MENU,null);
         Map<String ,String> mapMenu=new HashMap();
		if(!BlankUtil.isBlank(menuIDList)){
        	 for(String tempMenuList:menuIDList){
        		 mapMenu.put(tempMenuList.trim(), tempMenuList.trim());
        		 mapUrl.put(tempMenuList.trim(), tempMenuList.trim());
             }
        	 menuIDList=null;
         }


		 //从权限组件获得当前登录用户BUTTON权限，即按钮权限，为字符串数组
		List<String> buttonList = rightService.getAllFunctionEntitiesByType(organizationalStructureVO.getAccountId(),USER_RIGHT_TYPE_BUTTON, null);
		 Map<String ,String> mapButton=new HashMap();
			if(!BlankUtil.isBlank(buttonList)){
	        	 for(String tempButtonList:buttonList){
	        		 mapButton.put(tempButtonList.trim(), tempButtonList.trim());
	        		 mapUrl.put(tempButtonList.trim(), tempButtonList.trim());
	             }
	        	 buttonList=null;
	         }


		//获得所有的受控权限
//		Map<String,String> allMap=new HashMap();
//		List<ComAuthEntityDO> comAuthEntityList=authFunctionEntityManagementService.searchFunctionEntities(null, null, AuthEntityState.getInstance(1),null, null);
//		for(ComAuthEntityDO tempObject:comAuthEntityList){
//			allMap.put(tempObject.getName().trim(), tempObject.getName().trim());
//		}
//		comAuthEntityList=null;


		authInfo.setUrlMap(mapUrl);
		authInfo.setMenuIDMap(mapMenu);
		authInfo.setButtonMap(mapButton);
		return authInfo;
	}

	/**
	 * 判断session中是否已经存在登陆用户信息
	 * @param request
	 * @return
	 */
	private boolean isUserInfoInSession(HttpServletRequest request){
		OrganizationalStructureVO loginUser = (OrganizationalStructureVO) request.getSession().getAttribute(LOGIN_USER_KEY);
		String userCode = getCurrentLoginName(request);
		if(loginUser!=null && userCode!=null)
		{
			return loginUser.getUserCode().equals(userCode);
		}
		return false ;
	}


	/**
	 * Function:
	 * 跳转页面
	 * @param
	 * @return Create author:
	 */
	private void forwardPage(ServletRequest request,
			ServletResponse response, String url) throws ServletException, IOException {
		HttpServletRequest servletRequest = (HttpServletRequest) request;
		servletRequest.getRequestDispatcher(url).forward(request, response);
	}

	/**
	 * 获取当前用户登录名称
	 * @param request
	 * @return
	 */
	private String getCurrentLoginName(HttpServletRequest request){
		return (String)request.getSession().getAttribute(LoginAction.LOGIN_USER);
//		Principal principal = (Principal)request.getSession().getAttribute(CasClientConstants.UAMS_CAS_PRINCIPAL_SESSION_KEY);
//		return principal.getName();
	}

	public void init(FilterConfig config) {
		this.bizSystemSerialNumber = config.getServletContext().getInitParameter(BIZ_SYSTEM_SERIAL_NUMBER_KEY);
		applicationContext = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
	}

	public void destroy() {

	}

}
